﻿using System;
using System.Collections.Generic;
using Internal.Runtime.Services.Battle;
using Runtime.Services.Battle.Entity;
using Runtime.Services.BattleSkill;

namespace Runtime.Services.Battle {

    /// <summary>
    /// 战斗复杂数据
    /// </summary>
    public interface IDFR_ReadOnlyBattleComplexData : IReadOnlyF64ComplexData, IDFR_ReadOnlyBattleData {

        new IDFR_BattleComplexData AsReadWrite();
    }

    /// <summary>
    /// 战斗复杂数据
    /// </summary>
    public interface IDFR_ValueChangedBattleComplexData : IDFR_ReadOnlyBattleComplexData, IValueChangedF64ComplexData, IDFR_ValueChangedBattleData {
    }

    /// <summary>
    /// 战斗复杂数据
    /// </summary>
    public interface IDFR_BattleComplexData : IDFR_ValueChangedBattleComplexData, IComplexData<F64, IDFR_BattleFusionData> {

        /// <summary>
        /// 基础值
        /// </summary>
        new IDFR_BattleFusionData Base { get; }

        /// <summary>
        /// 系数
        /// </summary>
        new IDFR_BattleFusionData Factor { get; }

        /// <summary>
        /// 额外增值
        /// </summary>
        new IDFR_BattleFusionData Additional { get; }
    }

    [Implement(typeof(IDFR_ReadOnlyBattleComplexData))]
    [Implement(typeof(IDFR_ValueChangedBattleComplexData))]
    [Implement(typeof(IDFR_BattleComplexData))]
    internal sealed class DFR_BattleComplexData : KHBD_ComplexData<F64, IDFR_BattleFusionData, IDFR_BattleData>, IDFR_BattleComplexData, IDFR_ReadOnlyBattleFusionData.IItem, IDFR_BattleDataInternal {

        public DFR_BattleEntityInstanceID EntityInstanceID { get; private set; }

        protected override void Allocate() {
            base.Allocate();
            m_Base = (IDFR_BattleFusionData)Base;
            m_Factor = (IDFR_BattleFusionData)Factor;
            m_Additional = (IDFR_BattleFusionData)Additional;
            (m_Base as IDFR_BattleFusionDataInternal).SetIsRoot(true);
            (m_Factor as IDFR_BattleFusionDataInternal).SetIsRoot(true);
            (m_Additional as IDFR_BattleFusionDataInternal).SetIsRoot(true);
        }

        protected override void Release() {
            m_Base = null;
            m_Factor = null;
            m_Additional = null;
            EntityInstanceID = DFR_BattleEntityInstanceID.Empty;
            base.Release();
        }

        private IDFR_BattleFusionData m_Base;
        IDFR_BattleFusionData IDFR_BattleComplexData.Base {
            get {
                AssertDispose();
                return m_Base;
            }
        }

        private IDFR_BattleFusionData m_Factor;
        IDFR_BattleFusionData IDFR_BattleComplexData.Factor {
            get {
                AssertDispose();
                return m_Factor;
            }
        }

        private IDFR_BattleFusionData m_Additional;
        IDFR_BattleFusionData IDFR_BattleComplexData.Additional {
            get {
                AssertDispose();
                return m_Additional;
            }
        }

        void IDFR_BattleDataInternal.EnableFilter(DFR_BattleEntityInstanceID entityInstanceID) {
            AssertDispose();
            EntityInstanceID = entityInstanceID;
        }

        protected override F64 Calculate() {
            if (F64.MaxValue == Base.Value || F64.MaxValue == Factor.Value || F64.MaxValue == Additional.Value) {
                return F64.MaxValue;
            } else if (F64.MinValue == Base.Value || F64.MinValue == Factor.Value || F64.MinValue == Additional.Value) {
                return F64.MinValue;
            } else {
                return Base.Value * Factor.Value + Additional.Value; // TODO: 需要处理数字越界
            }
        }

        protected override F64 GetDefaultMaxValue() => F64.MaxValue;

        protected override F64 GetDefaultMinValue() => F64.MinValue;

        protected override F64 Clamp(F64 value, F64 min, F64 max) => F64.Clamp(value, min, max);

        IDFR_BattleData IDFR_ReadOnlyBattleData.AsReadWrite() => throw new NotSupportedException($"{nameof(IDFR_ReadOnlyBattleData)}.{nameof(IDFR_ReadOnlyBattleData.AsReadWrite)} 已被 {nameof(IDFR_ReadOnlyBattleComplexData)}.{nameof(IDFR_ReadOnlyBattleComplexData.AsReadWrite)} 覆盖");
        IDFR_BattleComplexData IDFR_ReadOnlyBattleComplexData.AsReadWrite() {
            AssertDispose();
            return this;
        }

        bool IDFR_ReadOnlyBattleFusionData.IItem.IsIgnore(IEnumerable<IDFR_ReadOnlyBattleFusionData.IItem> owner, IReadOnlyCollection<IDFR_ReadOnlyBattleFusionData.IItem> takedItems) {
            AssertDispose();
            return BattleSkillServiceBase.Instance.AsEffectFilter().IsIgnore(owner, this, takedItems);
        }
    }
}
